/**
 * Prototype for finder logic
 * 
 * @todo Needs a big refactoring
 * 
 * @version		prototype
 * @package		natural-api
 * 
 * @license		MIT-style license
 * @author		Harald Kirschner <mail [at] digitarald.de>
 * @copyright	Author
 */

var Site = {

	initialize: function() {
		Site.rows = $$('ul.row');
		Site.selected = [];

		var container = $('container');
		var autoHeight = function() {
			container.setStyle('height', Client.getHeight());
		};
		window.addEvent('resize', autoHeight);
		autoHeight();

		new Ajax('api/').request({
			filter: 'all'
		}).chain(function() {
			Site.generate(Json.decode(this.response.text));
		});

	},

	mapping: {
		'property': 'properties',
		'method': 'methods',
		'selector': 'selectors',
		'class': 'classes',
		'native': 'natives',
		'object': 'objects',
		'hash': 'hashes'
	},

	generate: function(data) {
		Site.tips = new Tips();
		Site.data = {
			all: data,
			scripts: {},
			namespaces: {},
			natives: [],
			classes: [],
			objects: [],
			hashes: [],
			methods: [],
			functions: [],
			selectors: [],
			events: []
		};

		Site.data.all = Site.data.all.filter(function(entry) {
			entry.keyword = entry.keyword.toLowerCase();
			entry.map = (Site.mapping[entry.keyword]) || entry.keyword + 's';
			switch (entry.keyword) {
				case 'script':
					this.scripts[entry.property] = entry;
					entry.children = [];
					break;
				case 'class':
				case 'object':
				case 'hash':
				case 'native':
					if (this.namespaces[entry.property]) return false;
					this.namespaces[entry.property] = entry;
					entry.children = [];
				default:
					if (this[entry.map]) this[entry.map].push(entry);
			};
			var id = entry.property, tmp;
			if ((tmp = entry.script)) this.scripts[tmp].children.push(entry);
			if ((tmp = entry.namespace)) {
				this.namespaces[tmp].children.push(entry);
				id = tmp + '.' + id;
			}
			entry.id = id;
			entry.fulltext = (entry.id + (entry.description || '') + (entry.script || '')).toLowerCase();
			entry.toString = function() {
				return this.id;
			}
			return true;
		}, Site.data);
		var scripts = [];
		for (var key in Site.data.scripts) scripts.push(Site.data.scripts[key]);
		delete Site.data.namespaces;
		Site.data.scripts = scripts;

		Site.data.all.each(function(entry) {
			if (entry.children) entry.children.sort();
		});
		Site.data.classes.sort();
		Site.data.scripts.sort();
		Site.data.functions.sort();
		Site.data.hashes.sort();
		Site.data.natives.sort();
		Site.data.objects.sort();
		Site.data.methods.sort();
		Site.data.selectors.sort();
		Site.data.events.sort();

		Site.rows[0].empty();
		var singles = {};
		for (var single in Site.mapping) {
			singles[Site.mapping[single]] = single;
		}
		$each(Site.data, function(val, key) {
			new Element('li', {
				'class': 'keyword-' + (singles[key] || key.slice(0, key.length - 1))
			}).setHTML(key.capitalize()).inject(Site.rows[0]).addEvent('click', function() {
				Site.createList(key, 1, this);
			});
		});

		var searchLi = new Element('li').inject(Site.rows[0])
		var obs = new Observer([
				new Element('input', {
					'type': 'text',
					'id': 'search-input'
				}).inject(searchLi),
				new Element('input', {
					'type': 'checkbox',
					'id': 'search-where',
					'title': 'Expand search to description'
				}).inject(searchLi)
			],
			function(values) {
				var input = values[0];
				if (input.length > 1) {
					var chunks = input.toLowerCase().split(' ');
					Site.data.search = Site.data.all.filter(function(entry) {
						var text = (values[1]) ? entry.fulltext : entry.id.toLowerCase();
						return chunks.every(text.contains, text);
					});
					Site.createList('search', 1, searchLi);
				}
			},
			{periodical: 500, delay: 300}
		);


		new Element('li', {
			title: "MIT-License applies for Code and Content"
		}).setHTML('(c) 2007 digitarald.de').inject(Site.rows[0]).addEvent('click', function() {
			location.href = 'http://digitarald.de';
		});

		window.addEvent('keydown', function(e) {
			if (!Site.selected.length) return;
			var target;
			switch (e.key) {
				case 'up':
					target = Site.selected.getLast().getPrevious();
					break;
				case 'down':
					target = Site.selected.getLast().getNext();
					break;
				case 'left':
				case 'backspace':
					if (Site.selected.length > 1) target = Site.selected[Site.selected.length - 2];
					break;
				case 'right':
				case 'enter':
					target = Site.rows[Site.selected.length - 1];
					if (target) target = target.getFirst();
					break;
				default:
					return;

			}
			if (target) target.fireEvent('click');
			e.stop();
		});
	},

	createList: function(prop, row, li) {
		if (Site.selected[row]) Site.selected[row].removeClass('selected');
		Site.selected.length = row + 1;
		Site.selected[row] = li.addClass('selected');
		var items;
		if ($type(prop) == 'string') items = Site.data[prop];
		else {
			items = prop.children;
			if (prop.description && !prop.details) {
				var item = new Element('li', {'class': 'details'});
				new Element('h5').setHTML(prop.id).inject(item);
				new Element('p', {'class': 'description'}).setHTML(prop.description).inject(item);
				if (prop.properties) {
					 $each(prop.properties, function(val, key) {
						new Element('h6').setHTML(key).inject(item);
						new Element('p').setHTML(val).inject(item);
					});
				}
				prop.details = item;
			}
		}
		if (items && !items.length) items = false;
		if (items) {
			var to = this.getLastRow(row);
			$each(items, function(val, key) {
				if (!val.li) {
					val.li = new Element('li', {
						title: val.id + (val.script ? ' <small>(' + val.script + ')</small>' : '') + ' :: ' + (val.description || '').wordCut(100, ' [...]') || item,
						'class': 'keyword-' + val.keyword
					}).setHTML(val.property || val);
					if (val['class']) new Element('small').setHTML('(' + val['class'] + ')').injectTop(val.li);
				}
				Site.tips.build(val.li.clone().addEvent('click', function() {
					Site.createList(val, row + 1, this);
				}).inject(to));
			}, this);
		}
		if (prop.details) prop.details.clone().inject(this.getLastRow(row + !!(items), true));
	},

	getLastRow: function(to, big) {
		if (!Site.rows[to]) Site.rows[to] = new Element('ul', {'class': 'row row-' + to}).injectAfter(Site.rows[to - 1]);
		else Site.rows[to].empty();
		if (this.lastRow != Site.rows[to]) {
			for (var i = Site.rows.length; (--i) > to;) Site.rows[i].empty().addClass('row-empty');
			if (this.lastRow) this.lastRow.removeClass('row-last');
			this.lastRow = Site.rows[to].removeClass('row-empty');
			if (big) this.lastRow.addClass('row-last');
		}
		return this.lastRow;
	}

};

window.addEvent('domready', Site.initialize);

String.extend({

	wordCut: function(max, append) {
		if (this.length < max) return this;
		var chunks = this.split(/\n| |<br ?\/>/);
		var ret = chunks[0];
		for (var i = 1, l = chunks.length; i < l && (ret.length + chunks[i].length) <= max; i++) {
			ret += ' ' + chunks[i];
		}
		return ret + (append || '...');
	}

});